home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / quartz / quartz10.lha / src / runtime / mcount.s < prev    next >
Text File  |  1990-05-08  |  4KB  |  199 lines

  1. #include "asmdefs.h"
  2.  
  3.     .file "mcount.s"
  4.     .data
  5.     .align 2
  6.     .text
  7.     .align 2
  8.     .globl mcountRet
  9.     .globl mcount
  10.     .globl _AtomicIncrPtr
  11.     .globl _AtomicDecrPtr
  12.  
  13. _AtomicIncrPtr:
  14.     movl 4(%esp) , %eax
  15.     lock incl (%eax)
  16.     ret
  17. _AtomicDecrPtr:
  18.     movl 4(%esp) , %eax
  19.     lock decl (%eax)
  20.     ret
  21.  
  22. /* I have to bend over backwards to make this re-entrant (interrupts)
  23.     and to work with dbx
  24.  
  25.     Initially, idPtr points to &idStack[0] with Start's ID.
  26. */
  27.  
  28. #define    FetchEPtr(t,e)    \
  29.     movl    [_pP + pP_thread] , t    ;\
  30.     movl    Thread_id_top(t) , e
  31.  
  32. /* Register definitions */
  33.  
  34. #define calleeID        %eax
  35. #define callerID        %ecx
  36. #define calleeFP        %edx
  37. #define callerPC        calleeFP
  38. #define graph            callerPC
  39.  
  40. #define me                %ecx
  41. #define ePtr            %edx
  42. #define tmpd            ePtr
  43.  
  44. #define        newFP        %eax
  45. #define        newCalleeFP        %eax
  46. #define        callerFP    %ecx
  47. #define        size2        callerFP
  48. #define     size1        calleeFP
  49.  
  50. /* Some random rare conditions */
  51. overflow:
  52.     pushl    calleeID        /* save for later */
  53.     pushl    callerID
  54.  
  55.     pushl    graph            /* args */
  56.     pushl    callerID
  57.     pushl    calleeID
  58.     call    _ProfileMustAdd
  59.     addl    $ 12 , %esp
  60.  
  61.     popl    callerID        /* get these back */
  62.     popl    calleeID
  63.     jmp        idStack
  64.  
  65. outOfRoom:
  66.     call    _OutOfRoom
  67.     jmp     done
  68.  
  69. tooHigh:
  70.     call    _TooHigh
  71.     jmp        done
  72.  
  73. recursiveCall:        /* clear the Overhead bit */
  74.     FetchEPtr(%edx,%edx)
  75.     movl    callerID, IdEntry_id(%edx)
  76.  
  77. done:
  78.     leave
  79. noProfile:
  80.     ret
  81.  
  82.  
  83. /* Entry point for procedures: assumes address of calleeID is loaded */
  84. mcount:
  85.     cmpl    $ 0 , _profileOn
  86.     je        noProfile
  87.  
  88.     pushl    %ebp
  89.     movl    %esp , %ebp
  90.  
  91.     FetchEPtr(%edx,%edx)
  92.     movl    IdEntry_id(%edx) , callerID
  93.     testl    $ OverheadState, callerID
  94.     jne        done
  95.  
  96.     orl        $ OverheadState , callerID
  97.     movl    callerID , IdEntry_id(%edx)
  98.  
  99.     andl    $ AllOffMask , callerID
  100. /* movl    (calleeID) , calleeID    */
  101.  
  102. /* uses calleeID, callerID, calleeFP == callerPC = graph */
  103. callCount:
  104.     movl    (%ebp) , calleeFP
  105.     movl    ReturnPC(calleeFP) , callerPC
  106.     cmpl    _mEndOfText , callerPC
  107.     jge        tooHigh
  108.     andl    $OffPCTableBits , callerPC
  109.     addl    _pcTable, callerPC    /* is now: graph */
  110.  
  111.     cmpl    Graph_calleeID(graph) , calleeID
  112.     jne        overflow
  113.     cmpl    Graph_callerID(graph) , callerID
  114.     jne        overflow
  115.     lock    incl    Graph_num(graph)
  116.  
  117. idStack:
  118.     cmpl    callerID, calleeID
  119.     je        recursiveCall            /* ignore recursive calls */
  120.  
  121. /* uses calleeID, me, ePtr */
  122.     FetchEPtr(me,ePtr)
  123.     cmpl    Thread_id_limit(me) , ePtr
  124.     jge        outOfRoom                        /* check for overflow */
  125.  
  126. fillIdEntry:
  127.     andl    $ OverheadOffMask, IdEntry_id(ePtr)
  128.     addl    $ IdSize , ePtr
  129.     movl    $ NoID , IdEntry_id(ePtr)
  130.     movl    ePtr , Thread_id_top(me)  
  131.  
  132. #ifdef PARANOID
  133.  
  134.     orl        $ OverheadState, calleeID
  135.     movl    calleeID , IdEntry_id(ePtr)
  136.  
  137. /* Munge the stack so that we return to mcountRet */
  138.  
  139. /* Assumes nothing is saved from above */
  140. mungeStack:
  141.     movl    (%ebp), calleeFP
  142.     movl    (calleeFP) , callerFP
  143.     subl    calleeFP , callerFP  /* now size2 */
  144.     subl    size2 , %esp
  145.     movl    %esp, newFP            /* save top of stack */
  146.     pushl    %esi
  147.     pushl    %edi
  148.     subl    %ebp , calleeFP        /* now size1 */
  149.     addl    size1 , size2        /* now size1 + size2 -- better be ecx */
  150.     shrl    $2, size2            /* # of words to be moved */
  151.  
  152.     movl    newFP , %edi
  153.     movl    %ebp, %esi
  154.  
  155. /* put us into a pseudo-stable intermediate state, before trashing old frame */
  156.     movl    (%ebp), %ebp
  157.  
  158.     rep        smovl
  159.  
  160.     addl    size1,newFP        /* now newCalleeFP = (oldCalleeFP + size2) */
  161.     movl    %ebp, (newCalleeFP)
  162.     movl    $ mcountRet, 4(newCalleeFP)
  163.     popl    %edi
  164.     popl    %esi
  165.     addl    $4, %esp    /* the fp that was saved on the stack is trash */
  166.     movl    newCalleeFP,%ebp
  167.  
  168. /* Turn off overhead flag */
  169.     movl    [_pP + pP_thread] , me
  170.     movl    Thread_id_top(me) , ePtr
  171.     andl    $ OverheadOffMask , IdEntry_id(ePtr)
  172.  
  173.     ret
  174.  
  175. /* Dont use eax -- it has the return value */
  176. mcountRet:
  177.     movl [_pP + pP_thread], me
  178.     addl $ - IdSize, Thread_id_top(me)
  179.     leave
  180.     ret
  181.  
  182. #else
  183.  
  184.     movl    calleeID , IdEntry_id(ePtr)
  185.     movl    (%ebp) , %ecx
  186.     movl    ReturnPC(%ecx) , %eax
  187.     movl    %eax , IdEntry_pc(ePtr)
  188.     movl    $ mcountRet , ReturnPC(%ecx)
  189.     leave
  190.     ret
  191.  
  192. /* don't use %eax */
  193. mcountRet:
  194.     FetchEPtr(me,ePtr)
  195.     movl    IdEntry_pc(ePtr),tmpd
  196.     addl    $ - IdSize, Thread_id_top(me)
  197.     jmp        *tmpd
  198. #endif
  199.